package com.mubai.framework.redis;

import org.springframework.data.geo.Metric;
import org.springframework.data.geo.Point;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author baichuanping
 * @create 2018-12-27
 */
public interface RedisService {
	/**
	 * 批量删除对应的value
	 * @param keys 参数
	 */
	public void remove(final String... keys);

	/**
	 * 批量删除key
	 * @param pattern 参数
	 */
	public void removePattern(final String pattern);

	/**
	 * 删除对应的value
	 * @param key 参数
	 */
	public void remove(final String key);

	/**
	 * 判断缓存中是否有对应的value
	 * @param key
	 * @return
	 */
	public boolean exists(final String key);

	/**
	 * 读取缓存
	 * @param key 参数
	 * @return
	 */
	public String get(final String key);

	/**
	 * 写入缓存，永久
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean set(final String key, String value);

	/**
	 * 写入缓存（有时间限制）
	 * @param key
	 * @param value
	 * @param expireTime 时间
	 * @param timeUnit 时间单位
	 * @return
	 */
	public boolean set(final String key, String value, Long expireTime, TimeUnit timeUnit);

	/**
	 * 获取指定key的范围内的value值的 list列表。 （0  -1）返回所有值列表
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	public List<String> range(final String key, Long start, Long end);

	/**
	 * 保留key指定范围内的列表值。其它的都删除。
	 * @param key
	 * @param start
	 * @param end
	 */
	public void trim(final String key, Long start, Long end);

	/**
	 * 获取key 列表的长度
	 * @param key
	 * @return
	 */
	public Long size(final String key);

	/**
	 * 写入缓存，是左面进入 先进后出
	 * @param key
	 * @param value
	 * @return
	 */
	public Long leftPush(final String key, String value);

	/**
	 * 多个值写入缓存，是左面进入 先进后出
	 * @param key
	 * @param values
	 * @return
	 */
	public Long leftPushAll(final String key, String... values);

	/**
	 * 如果列表存在，则在列表左边插入值value
	 * @param key
	 * @param value
	 * @return
	 */
	public Long leftPushIfPresent(final String key, String value);

	/**
	 * 在key的列表中指定的value左边（前面）插入一个新的value.如果 指定的value不存在则不插入任何值。
	 * @param key
	 * @param pivot
	 * @param value
	 * @return
	 */
	public Long leftPush(final String key, String pivot, String value);

	/**
	 * 写入缓存，是右边面进入 先进先出
	 * @param key
	 * @param value
	 * @return
	 */
	public Long rightPush(final String key, String value);

	/**
	 * 多个值写入缓存，是右边面进入 先进先出
	 * @param key
	 * @param values
	 * @return
	 */
	public Long rightPushAll(final String key, String... values);

	/**
	 * 如果列表存在，则在列表右边插入值value
	 * @param key
	 * @param value
	 * @return
	 */
	public Long rightPushIfPresent(final String key, String value);

	/**
	 * 在key的列表中指定的value右边（前面）插入一个新的value.如果 指定的value不存在则不插入任何值。
	 * @param key
	 * @param pivot
	 * @param value
	 * @return
	 */
	public Long rightPush(final String key, String pivot, String value);

	/**
	 * 置key列表中指定位置的值为value index不能大于列表长度。大于抛出异常,为负数则从右边开始计算
	 * @param key
	 * @param index
	 * @param value
	 */
	public void set(final String key, Long index, String value);

	/**
	 * 删除列表中第一个遇到的value值。count指定删除多少个,count为0则全部删除
	 * @param key
	 * @param count 大于0从左边开始，等于0全部删除，小于0从右边开始
	 * @param value
	 * @return
	 */
	public Long remove(final String key, Long count, Object value);

	/**
	 * 通过索引获取列表中的元素
	 * @param key
	 * @param index 大于0从左边开始，小于0从右边开始
	 * @return
	 */
	public String index(final String key, Long index);

	/**
	 * 移除列表中的第一个值，并返回该值
	 * @param key
	 * @return
	 */
	public String leftPop(final String key);

	/**
	 * 移除列表中的第一个值，如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
	 * @param key
	 * @param timeout
	 * @param unit
	 * @return
	 */
	public String leftPop(final String key, Long timeout, TimeUnit unit);

	/**
	 * 移除列表中的最后一个值，并返回该值
	 * @param key
	 * @return
	 */
	public String rightPop(final String key);

	/**
	 * 移除列表中的最后一个值，如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
	 * @param key
	 * @param timeout
	 * @param unit
	 * @return
	 */
	public String rightPop(final String key, Long timeout, TimeUnit unit);

	/**
	 * 从指定列表中从右边（尾部）移除第一个值，并将这个值从左边（头部）插入目标列表
	 * @param sourceKey
	 * @param destinationKey
	 * @return
	 */
	public String rightPopAndLeftPush(final String sourceKey,final String destinationKey);

	/**
	 * 从指定列表中从右边（尾部）移除第一个值，并将这个值从左边（头部）插入目标列表，如果移除的列表中没有值，则一直阻塞指定的单位时间
	 * @param sourceKey
	 * @param destinationKey
	 * @param timeout
	 * @param unit
	 * @return
	 */
	public String rightPopAndLeftPush(final String sourceKey, final String destinationKey, Long timeout, TimeUnit unit);

	//////////////////////////////////////////////GEO///////////////////////////////////////////////////

	/**
	 * 添加geo
	 * @param key
	 * @param point
	 * @param member
	 * @return
	 */
	public Long geoAdd(String key, String point, String member);

	/**
	 * 删除成员
	 * @param key
	 * @param members
	 * @return
	 */
	public Long geoRemove(String key, String... members);

	/**
	 * 查询地址的经纬度
	 * @param key
	 * @param members
	 * @return
	 */
	public List<Point> geoPos(String key, String... members);

	/**
	 * 查询位置的geohash
	 * @param key
	 * @param members
	 * @return
	 */
	public List<String> geoHash(String key, String... members);

	/**
	 * 查询2位置距离
	 * @param key
	 * @param member1
	 * @param member2
	 * @param metric
	 * @return
	 */
	public Double geoDist(String key, String member1, String member2, Metric metric);
}
